package com.googlecode.afdbaccess.commandlinedemo;

import java.util.List;

import org.apache.log4j.Logger;

import com.googlecode.afdbaccess.cache.DbCache;
import com.googlecode.afdbaccess.cache.Transaction;
import com.googlecode.afdbaccess.cache.connectionpool.interfaces.ConnectionPool;
import com.googlecode.afdbaccess.cache.connectionpool.interfaces.ConnectionPoolFactory;
import com.googlecode.afdbaccess.cache.exceptions.DataLayerException;
import com.googlecode.afdbaccess.cache.exceptions.DataLayerWrappedSqlException;
import com.googlecode.afdbaccess.commandlinedemo.db.Insert;
import com.googlecode.afdbaccess.commandlinedemo.db.NormalQuery;
import com.googlecode.afdbaccess.commandlinedemo.db.SimpleQuery;
import com.googlecode.afdbaccess.commandlinedemo.db.Update;
import com.googlecode.afdbaccess.commandlinedemo.db.NormalQuery.NormalQueryResult;
import com.googlecode.afdbaccess.config.propertyconfig.ReadConfiguration;


public class CommandLineDemo {
    protected static final Logger logger = Logger.getLogger(CommandLineDemo.class);

    public CommandLineDemo() throws Throwable {
        logger.debug("Trying to initiate DB access objects.");
        ConnectionPoolFactory connectionPoolFactory = ReadConfiguration.instanciatePoolFactory();
        ConnectionPool connectionPool = connectionPoolFactory.getNewConnectionPool();
        DbCache dbCache = new DbCache(connectionPool);
        try {
            logger.debug("DB access object initiated!");
    
            Transaction transaction = new Transaction(dbCache);
    
            try {
                doInsert(transaction);
    
                doSimpleQuery(transaction);
    
                doUpdate(transaction); // Deletes are done the same way, just different SQL
    
                doNormalQuery(transaction);
                
                // repeat query to demonstrate cache
                doNormalQuery(transaction);
    
                // If there were no exceptions, this commit will be reached
                transaction.commit();
            } finally {
                // if commit or rollback isn't run before this, this call will log a warning, and do an automatic rollback
                transaction.close();
            }
        } finally {
            dbCache.close();
        }
    }
    
    private void doInsert(Transaction t) throws DataLayerException {
        long primaryKeyOfNewRow = Insert.doInsert(t);
        
        logger.info("Primary key returned from the insert: " + primaryKeyOfNewRow);
    }

    private void doSimpleQuery(Transaction t) throws DataLayerException {
        String result = SimpleQuery.doSimpleQuery(t);
        
        logger.info("Result from simpleQuery: " + result);
    }
    
    private void doUpdate(Transaction t) throws DataLayerWrappedSqlException, DataLayerException {
        int numberOfRowsThatWasModified = Update.doUpdate(t);
        
        logger.info("Number of updated rows: " + numberOfRowsThatWasModified);
    }

    private void doNormalQuery(Transaction t) throws DataLayerException {
        List<NormalQueryResult> rows = NormalQuery.doNormalQuery(t);

        logger.info("Result from normal query:");
        
        for(NormalQuery.NormalQueryResult row : rows) {
            logger.info(row.id + " = " + row.name);
        }

        for(int rowCounter = 0; rowCounter < rows.size(); rowCounter++) {
            NormalQuery.NormalQueryResult row = rows.get(rowCounter);
            logger.info("Row #" + rowCounter +": " + row.id + " = " + row.name);
        }
    }

    public static void main(String[] args) throws Throwable {
        try {
            new CommandLineDemo();
        } catch (Throwable t) {
            logger.fatal("Unhandled exception occured!", t);
            throw t;
        }
    }
}
